<?php
declare (strict_types = 1);

namespace app\api\middleware;

use app\api\model\Admin;
use app\api\model\Auth;
use app\api\model\Role;
use app\api\service\Token;
use think\Exception;
use think\exception\HttpException;
use think\facade\Cache;

class Check
{
    /**
     * 处理请求
     *
     * @param \think\Request $request
     * @param \Closure       $next
     * @return Response
     */
    public function handle($request, \Closure $next)
    {
        //
        try {

            // 验证token
            $user_id = (new Token())->decode();
            if (!$user_id) {
                abort(2001,'请先登录');
            }
            // 权限检测
            $this->authCheck($user_id);
            
            // 频率限制
//            $this->throttle();
            
            // 所有的验证通过
            return  $next($request);
        }catch (Exception $exception) {
            return  fail([],$exception->getMessage(),$exception->getCode());
        }catch (HttpException $httpException) {
            return  fail([],$httpException->getMessage(),$httpException->getCode());
        }


    }

    /**
     * 权限检测
     * @param $user_id
     * @return bool
     */
    protected function authCheck($user_id){
        $adminInfo = Admin::find($user_id);
        if ($adminInfo->role_id == 1) {
            # 超级不需要进行权限检测
            return true;
        }

        # 根据角色id查询对应的权限
        # 根据角色di查询权限id
        $auth_ids =Role::find($adminInfo->role_id)->auth_ids;
        # 根据权限id查询权限
        $auth = Auth::whereIn('id',$auth_ids)->select()->toArray();
        $adminAuth = [];
        # 处理权限数据
        foreach ($auth as $value) {
            $adminAuth[] = $value['controller'].'/'.$value['action'];
        }
        # 查询出来当前用户的权限
        $adminAuth = array_unique($adminAuth);
        # 当前访问的权限
        $current = strtolower(request()->controller()).'/'.strtolower(request()->action());

        if (in_array($current,$adminAuth)) {
            return  true;
        }

        abort(4003,'无权限访问');

    }

    /**
     * 频率检测
     */
    protected function throttle(){
        $key = md5(request()->controller().request()->action().request()->ip());
        $is_request = Cache::get($key);
        if (empty($is_request)) {
            Cache::set($key,1,60);
        }elseif ($is_request >= 3) {
            abort(4003,'请求频率过多、请稍后重试');
        } else {
            Cache::inc($key);
        }
    }
}
